// 2013年版权归Go作者所有。版权所有。
// 此源代码的使用受BSD样式的约束
// 可以在许可证文件中找到的许可证。

package json

import (
	"bytes"
	"unicode/utf8"
)

const (
	caseMask     = ^byte(0x20) // 掩码以忽略ASCII中的大小写。
	kelvin       = '\u212a'
	smallLongEss = '\u017f'
)

// foldFunc返回四种不同大小写折叠等价中的一种
// 功能，从最普通（和最慢）到最快：
// None
// 1） bytes.EqualFold，如果密钥s包含任何非ASCII UTF-8
// 2） equalFoldRight，如果s包含特殊的折叠ASCII（'k'，'k'，'s'，'s'）
// 3） asciiEqualFold，无特殊，但包括非字母（包括)
// 4） simpleLetterEqualFold，没有特价，没有非字母。
// None
// 字母S和K是特殊的，因为它们映射到3个符文，而不仅仅是2个：
// None
// None
// 请参阅https:
// None
// 返回的函数专门用于匹配s和
// 应该只给s。它不是出于性能原因而咖喱的。
func foldFunc(s []byte) func(s, t []byte) bool {
	nonLetter := false
	special := false // 特别信件
	for _, b := range s {
		if b >= utf8.RuneSelf {
			return bytes.EqualFold
		}
		upper := b & caseMask
		if upper < 'A' || upper > 'Z' {
			nonLetter = true
		} else if upper == 'K' || upper == 'S' {
			// 请参见上文，了解这些字母的特殊性。
			special = true
		}
	}
	if special {
		return equalFoldRight
	}
	if nonLetter {
		return asciiEqualFold
	}
	return simpleLetterEqualFold
}

// equalFoldRight是字节的专门化。当s为
// 已知为所有ASCII码（包括标点符号），但包含“s”，
// 'S'、'k'或'k'，需要对t中的字节进行Unicode折叠。
// 参见foldFunc上的注释。
func equalFoldRight(s, t []byte) bool {
	for _, sb := range s {
		if len(t) == 0 {
			return false
		}
		tb := t[0]
		if tb < utf8.RuneSelf {
			if sb != tb {
				sbUpper := sb & caseMask
				if 'A' <= sbUpper && sbUpper <= 'Z' {
					if sbUpper != tb&caseMask {
						return false
					}
				} else {
					return false
				}
			}
			t = t[1:]
			continue
		}
		// sb是ASCII，t不是。t必须是开尔文
		// 符号或长s；某人必须是s、s、k或k。
		tr, size := utf8.DecodeRune(t)
		switch sb {
		case 's', 'S':
			if tr != smallLongEss {
				return false
			}
		case 'k', 'K':
			if tr != kelvin {
				return false
			}
		default:
			return false
		}
		t = t[size:]

	}
	if len(t) > 0 {
		return false
	}
	return true
}

// asciiEqualFold是bytes.EqualFold的专门化，用于
// s是所有ASCII码（但可能包含非字母），不包含任何字符
// 特殊的折叠字母。
// 参见foldFunc上的注释。
func asciiEqualFold(s, t []byte) bool {
	if len(s) != len(t) {
		return false
	}
	for i, sb := range s {
		tb := t[i]
		if sb == tb {
			continue
		}
		if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
			if sb&caseMask != tb&caseMask {
				return false
			}
		} else {
			return false
		}
	}
	return true
}

// simpleLetterEqualFold是字节的专门化。EqualFold用于
// 当s为所有ASCII字母（无下划线等）且
// 不包含“k”、“k”、“s”或“s”。
// 参见foldFunc上的注释。
func simpleLetterEqualFold(s, t []byte) bool {
	if len(s) != len(t) {
		return false
	}
	for i, b := range s {
		if b&caseMask != t[i]&caseMask {
			return false
		}
	}
	return true
}
